package com.example.afinal.offlineupdate.update;


import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * APK更新功能
 * Created by gw on 2015/12/28.
 */
public class ApkUpdateUtils {
    private static final String TAG = ApkUpdateUtils.class.getSimpleName();
    private static ApkUpdateUtils mInstance;
    private ExecutorService executorService = Executors.newSingleThreadExecutor();

    private ApkUpdateUtils(){}
    /**
     * 获取实例
     * @return
     */
    public static ApkUpdateUtils getInstance() {
        if (mInstance == null) {
            synchronized (ApkUpdateUtils.class) {
                if (mInstance == null) {
                    mInstance = new ApkUpdateUtils();
                }
            }
        }
        return mInstance;
    }

    /**
     * 检查本地SD卡、U盘等根目录下是否有新版本的APK，有则自动安装, 带加载提示
     * @param context 上下文
     */
    public void checkLocalUpdate(Context context){
        Intent intent = new Intent(context, UpdateActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra("action", UpdateActivity.CHECK_LOCAL_UPDATE);
        context.startActivity(intent);
    }

    /**
     * 检查本地SD卡、U盘等根目录下是否有新版本的APK，有则自动安装, 不带加载提示
     * @param context 上下文
     */
    public void checkLocalUpdateAtBackground(final Context context){
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                File apkFile = findUpdatePackage(context, Environment.getExternalStorageDirectory().getAbsolutePath());
                if(apkFile == null){
                    apkFile = findUpdatePackage(context, "/storage/extsd");
                }
                if(apkFile == null){
                    apkFile = findUpdatePackage(context, "/storage/usbhost1");
                }
                if(apkFile == null){
                    apkFile = findUpdatePackage(context, "/storage/usbhost2");
                }
                if(apkFile == null){
                   return;
                }
                File msg = new File(apkFile.getParent(), apkFile.getName().replace(".apk", ".txt"));
                String description = readStringFile(msg);
                Intent intent = new Intent(context, UpdateActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("action", UpdateActivity.CHECK_UPDATE_MSG);
                intent.putExtra("apk", apkFile.getAbsolutePath());
                intent.putExtra("description", description);
                context.startActivity(intent);
            }
        });
    }

    /**
     * 检查指定目录下是否有新版本的APK，有则自动安装, 不带加载提示
     * @param context 上下文
     * @param path 需要检查的目录
     */
    public void checkLocalUpdateAtBackground(final Context context, final String path){
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                File apkFile = findUpdatePackage(context, path);
                if(apkFile == null){
                    return;
                }
                File msg = new File(apkFile.getParent(), apkFile.getName().replace(".apk", ".txt"));
                String description = readStringFile(msg);
                Intent intent = new Intent(context, UpdateActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("action", UpdateActivity.CHECK_UPDATE_MSG);
                intent.putExtra("apk", apkFile.getAbsolutePath());
                intent.putExtra("description", description);
                context.startActivity(intent);
            }
        });
    }

    /**
     * 检查指定目录下是否存在高版本的更新包，并返回结果
     * @param path  检查目录
     * @return  APK文件
     */
    public File findUpdatePackage(Context context, String path) {
        File parent = new File(path);
        if(!parent.exists() || parent.isFile()){
            return null;
        }
        File[] apks = parent.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().toLowerCase().endsWith(".apk");
            }
        });
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            File apkFile = null;
            int versionCode = 0;
            for(File apk : apks){
                PackageInfo apkInfo = packageManager.getPackageArchiveInfo(apk.getAbsolutePath(), 0);
                if(packageInfo.packageName.equals(apkInfo.packageName) && packageInfo.versionCode < apkInfo.versionCode){
                    if(apkFile == null){
                        apkFile = apk;
                        versionCode = apkInfo.versionCode;
                    }else{
                        if(versionCode < apkInfo.versionCode){
                            apkFile = apk;
                            versionCode = apkInfo.versionCode;
                        }
                    }
                }
            }
            return apkFile;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 启动silentinstall service静默安装服务
     * @param context 上下文
     * @param path apk绝对路径
     */
    public void silentInstall(Context context, String path) {
        Intent intent = new Intent("silentinstall");
        intent.setPackage("cn.rayland.service");
        intent.putExtra("apkPath", path);
        context.startService(intent);
    }

    /**
     * 将文件内容读取成String
     * @param file 要读取的文件
     * @return 文件内容
     */
    public String readStringFile(File file){
        StringBuilder builder = new StringBuilder();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "GBK"));
            String line;
            while((line = br.readLine())!=null){
                builder.append(line);
                builder.append("\n");
            }
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }finally {
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return builder.toString();
    }

}
